package com.niiwoo.civet.trade.service.local.databackflow.listener;

import com.alibaba.fastjson.JSON;
import com.dangdang.ddframe.rdb.sharding.api.HintManager;
import com.dangdang.ddframe.rdb.sharding.hint.HintManagerHolder;
import com.niiwoo.civet.trade.dao.entity.DataBackflowDetails;
import com.niiwoo.civet.trade.dao.entity.DataBackflowStatus;
import com.niiwoo.civet.trade.dao.entity.ProjectLoanDeviceInfo;
import com.niiwoo.civet.trade.dao.mapper.DataBackflowDetailsMapperExt;
import com.niiwoo.civet.trade.dao.mapper.DataBackflowStatusMapperExt;
import com.niiwoo.civet.trade.dao.mapper.ProjectLoanDeviceInfoMapperExt;
import com.niiwoo.civet.trade.enums.DataBackflowStatusDataStatusEnum;
import com.niiwoo.civet.trade.enums.DataBackflowStatusDataTypeEnum;
import com.niiwoo.civet.trade.service.local.databackflow.DataBackflowService;
import com.niiwoo.tripod.tiancheng.component.TianchengDataFlowService;
import com.niiwoo.tripod.tiancheng.request.df.AddressListRequest;
import com.niiwoo.tripod.tiancheng.response.common.TianchengUapResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.CompletableFuture;

/**
 * @author wping
 * @Description: 通讯录回流监听器
 * @date 2018/4/18 17:19
 */
@Slf4j
@Component
public class AddressListListener implements DataBackflowListener {

    @Autowired
    private DataBackflowStatusMapperExt dataBackflowStatusMapperExt;

    @Autowired
    private DataBackflowDetailsMapperExt dataBackflowDetailsMapperExt;

    @Autowired
    private ProjectLoanDeviceInfoMapperExt projectLoanDeviceInfoMapper;

    @Autowired
    private TianchengDataFlowService tianchengDataFlowService;

    @Autowired
    private DataBackflowService dataBackflowService;

    @Override
    public void handle(Long flowExecuteId, String userId, Long projectId, int currentExecuteTimes) {

        final String methodName = "通讯录回流监听到回流请求, flowExecuteId:" + flowExecuteId + ", userId:" + userId + ", projectId:" + projectId;
        if (flowExecuteId == null || StringUtils.isEmpty(userId) || projectId == null) {
            log.error(methodName + "-flowExecuteId/userId/projectId为空");
            return;
        }

        if (!HintManagerHolder.isMasterRouteOnly()) {
            HintManagerHolder.clear();
            HintManager hintManager = HintManager.getInstance();
            hintManager.setMasterRouteOnly();
        }
        // 查询最近一次回流状态情况
        DataBackflowStatus dataBackflowStatus = dataBackflowStatusMapperExt.selectByUserIdProjectIdWithDataType(userId, projectId, DataBackflowStatusDataTypeEnum.ADDRESS_LIST.getType());
        if (dataBackflowStatus != null) {
            if (DataBackflowStatusDataStatusEnum.BACKFLOW_SUCCESSED.getStatus().byteValue() == dataBackflowStatus.getDataStatus().byteValue()) {
                log.info(methodName + "-数据已经回流，无需重复回流");
                return;
            }
            if (DataBackflowStatusDataStatusEnum.FAILED.getStatus().byteValue() == dataBackflowStatus.getDataStatus().byteValue()) {
                log.info(methodName + "-数据已经回流失败, 非待回流状态");
                return;
            }

            if (DataBackflowStatusDataStatusEnum.WAITING_BACKFLOW.getStatus().byteValue() == dataBackflowStatus.getDataStatus().byteValue()
                    || DataBackflowStatusDataStatusEnum.FAILED_WITH_RETRY.getStatus().byteValue() == dataBackflowStatus.getDataStatus().byteValue()) {
                try {
                    if (dataBackflowStatus.getDetailsId() == null) {
                        log.error(methodName + "-回流失败，回流详情ID不存在");
                        dataBackflowService.updateAndNotifyBackflowStatusChange(flowExecuteId, false, dataBackflowStatus, currentExecuteTimes, "回流失败，回流详情ID不存在");
                        return;
                    }

                    if (!HintManagerHolder.isMasterRouteOnly()) {
                        HintManagerHolder.clear();
                        HintManager hintManager = HintManager.getInstance();
                        hintManager.setMasterRouteOnly();
                    }
                    DataBackflowDetails dataBackflowDetails = dataBackflowDetailsMapperExt.selectByPrimaryKey(dataBackflowStatus.getDetailsId());
                    if (dataBackflowDetails == null) {
                        log.error(methodName + "-回流失败，回流详情记录不存在");
                        dataBackflowService.updateAndNotifyBackflowStatusChange(flowExecuteId, false, dataBackflowStatus, currentExecuteTimes, "回流失败，回流详情记录不存在");
                        return;
                    }

                    ProjectLoanDeviceInfo projectLoanDeviceInfo = projectLoanDeviceInfoMapper.selectByUserIdAndProjectId(userId, projectId);
                    if (projectLoanDeviceInfo == null) {
                        log.error(methodName + "-回流失败，设备信息记录不存在");
                        dataBackflowService.updateAndNotifyBackflowStatusChange(flowExecuteId, false, dataBackflowStatus, currentExecuteTimes, "回流失败，设备信息记录不存在");
                        return;
                    }

                    byte[] bytes = Base64.decodeBase64(dataBackflowDetails.getContents());
                    String addresslistStr = new String(bytes);
                    if (StringUtils.isEmpty(addresslistStr)) {
                        log.error(methodName + "-回流失败，通讯录内容为空");
                        dataBackflowService.updateAndNotifyBackflowStatusChange(flowExecuteId, false, dataBackflowStatus, currentExecuteTimes, "回流失败，通讯录内容为空");
                        return;
                    }

                    AddressListRequest addressListRequest = new AddressListRequest();
                    addressListRequest.setAddressList(JSON.parseArray(addresslistStr).toJavaList(AddressListRequest.Address.class));
                    addressListRequest.setEquipmentStatus(projectLoanDeviceInfo.getDeviceStatus() != null ? projectLoanDeviceInfo.getDeviceStatus().intValue() : 0);
                    addressListRequest.setOs(projectLoanDeviceInfo.getOs());
                    addressListRequest.setDeviceId(projectLoanDeviceInfo.getDeviceId());
                    addressListRequest.setUserId(userId);

                    log.info(methodName + "-天称通讯录回流开始，请求参数={}", JSON.toJSONString(addressListRequest));
                    CompletableFuture<TianchengUapResponse> completableFuture = tianchengDataFlowService.addressList(addressListRequest);
                    completableFuture.whenComplete((s, t) -> {
                        // 成功
                        if (s != null) {
                            TianchengUapResponse tianchengUapResponse = (TianchengUapResponse) s;
                            //回流成功
                            if (tianchengUapResponse.isSuccess()) {
                                log.info(methodName + "天称通讯录回流成功，返回报文:{}", JSON.toJSONString(tianchengUapResponse));
                                dataBackflowService.updateAndNotifyBackflowStatusChange(flowExecuteId, true, dataBackflowStatus, currentExecuteTimes, tianchengUapResponse.getStatus() + "_" + tianchengUapResponse.getMessage());
                            } else {
                                //回流失败
                                log.info(methodName + "天称通讯录回流失败，返回报文:{}", JSON.toJSONString(tianchengUapResponse));
                                dataBackflowService.updateAndNotifyBackflowStatusChange(flowExecuteId, false, dataBackflowStatus, currentExecuteTimes, tianchengUapResponse.getStatus() + "_" + tianchengUapResponse.getMessage());
                            }
                        }
                        // 异常
                        if (t != null) {
                            log.error(methodName + "天称通讯录回流异常，异常信息:{}", t);
                            dataBackflowService.updateAndNotifyBackflowStatusChange(flowExecuteId, false, dataBackflowStatus, currentExecuteTimes, t.getMessage());
                        }
                    });
                } catch (Exception e) {
                    log.error(methodName + "-回流异常", e);
                    dataBackflowService.updateAndNotifyBackflowStatusChange(flowExecuteId, false, dataBackflowStatus, currentExecuteTimes, "未知异常");
                }
            }
        } else {
            log.error(methodName + "-未查询到DataBackflowStatus数据，请初始化数据...");
        }
    }

    @Override
    public boolean isBackflowSuccess(String userId, Long projectId) {
        return dataBackflowService.isBackflowSuccess(userId, projectId, DataBackflowStatusDataTypeEnum.ADDRESS_LIST);
    }
}
